package com.wuye.controller;

import com.wuye.model.Order;
import com.wuye.repository.OrderRepository;
import com.wuye.service.OrderService;
import com.wuye.web.*;
import com.wuye.weixin.QyWeixin;
import com.wuye.weixin.WeixinException;
import com.wuye.weixin.WeixinManager;
import com.wuye.weixin.pay.PayNotifyResult;
import com.wuye.weixin.wxPay.WeiXinService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom.input.SAXBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.xml.sax.InputSource;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.StringReader;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jdom.Document;
import org.jdom.Element;

/**
 * Created by jiawenlong on 2016/6/21.
 */
@Controller
@RequestMapping("/weixin")
public class WeixinPayController {
    private Log log = LogFactory.getLog(this.getClass());
    @Autowired
    private WeiXinService weiXinService;
    @Autowired
    private SessionHandler sessionHandler;
    @Autowired
    private OrderRepository orderRepository;
    @Autowired
    private OrderService orderService;
    @Autowired
    private AppConfig appConfig;

    @RequestMapping("/weixinPay.jspx")
    public String weixinPay(Model model, @RequestParam("sn") String sn, HttpSession session, HttpServletResponse response, HttpServletRequest req) {
        try {
            UserSession userSession = sessionHandler.getUserSession(session);
            String userId = userSession.getUserId();
            QyWeixin weixin = WeixinManager.getWeixin();
            String openId = weixin.convertToOpenId(userId);
            log.info("微信支付从userId转换成openId=" + openId);
            String param = new Http(appConfig.getHost()+"/weixin/getWeixinJSPayPackage.jspx").param("sn", sn).param("openId", openId).post().getString("result");
            //根据请求结果判定，是否验证成功
            // upfoodService.getWeixinJSPayPackage( sn, openId);
            log.info("微信支付GET openId:" + openId + "\n" + param);
            model.addAttribute("jsPayParam", URLEncoder.encode(param, "utf-8"));
            log.info("微信支付GET URLEncoder.encode：" + URLEncoder.encode(param, "utf-8"));
            model.addAttribute("sn", sn);
            model.addAttribute("host", appConfig.getHost());

        } catch (WeixinException e) {
            log.error("=======================weixinLogin获取用户时出现异常============================", e);
        } catch (IOException e) {
            log.error("========================跳转报错================================");
        }
        return "/jspa/order/weixinPay";
    }

    @RequestMapping("/weixinPayGo.jspx")
    public String weixinPay() {
        return "/jspa/order/weixinPayGo";
    }

    @ResponseBody
    @RequestMapping("/getWeixinJSPayPackage.jspx")
    public String getWeixinJSPayPackage(@RequestParam("sn") String sn, @RequestParam("openId") String openId) {
        Order order = orderRepository.findOne(sn);
        if (null != order) {
            return ST.ok.getJsonObject(weiXinService.getPackage(order.getTotalPrice().toString(), sn, openId)).toString();
        } else {
            return ST.dataNotExists.toJson();
        }
    }

    @ResponseBody
    @RequestMapping("/weixin_notify_url.jspx")
    public void notify_url(HttpServletRequest request, HttpServletResponse response) throws Exception {
        log.info("微信支付回调数据开始");
        String inputLine;
        String notityXml = "";
        String resXml;
        try {
            while ((inputLine = request.getReader().readLine()) != null) {
                notityXml += inputLine;
            }
            request.getReader().close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        log.info("接收到的报文：" + notityXml);

        Map m = parseXmlToList2(notityXml);
        PayNotifyResult wpr = new PayNotifyResult();
        wpr.setAppid(m.get("appid").toString());
        wpr.setBank_type(m.get("bank_type").toString());
        wpr.setCash_fee(m.get("cash_fee").toString());
        wpr.setFee_type(m.get("fee_type").toString());
        wpr.setIs_subscribe(m.get("is_subscribe").toString());
        wpr.setMch_id(m.get("mch_id").toString());
        wpr.setNonce_str(m.get("nonce_str").toString());
        String openId = m.get("openid").toString();
        wpr.setOpenid(openId);
        String out_trade_no = m.get("out_trade_no").toString();
        wpr.setOut_trade_no(out_trade_no);
        wpr.setResult_code(m.get("result_code").toString());
        wpr.setReturn_code(m.get("return_code").toString());
        wpr.setSign(m.get("sign").toString());
        wpr.setTime_end(m.get("time_end").toString());
        wpr.setTotal_fee(m.get("total_fee").toString());
        wpr.setTrade_type(m.get("trade_type").toString());
        String tid = m.get("transaction_id").toString();
        wpr.setTransaction_id(tid);

        if ("SUCCESS".equals(wpr.getResult_code())) {
            log.info("回调参数: sn=" + out_trade_no + ";trade_no=" + openId + ";" + tid + ";trade_status=SUCCESS");
            Object object;
            object = orderService.doOrder(out_trade_no, openId + ";" + tid, "SUCCESS", "微信");
            //支付成功
            resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                    + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
        } else {
            resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                    + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }
        log.info("微信支付回调数据结束");
        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
        out.write(resXml.getBytes());
        out.flush();
        out.close();
    }

    /**
     * description: 解析微信通知xml
     *
     * @param xml
     * @return
     * @author ex_yangxiaoyi
     * @see
     */
    private static Map parseXmlToList2(String xml) {
        Map retMap = new HashMap();
        try {
            StringReader read = new StringReader(xml);
            // 创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
            InputSource source = new InputSource(read);
            // 创建一个新的SAXBuilder
            SAXBuilder sb = new SAXBuilder();
            // 通过输入源构造一个Document
            Document doc = (Document) sb.build(source);
            Element root = doc.getRootElement();// 指向根节点
            List<Element> es = root.getChildren();
            if (es != null && es.size() != 0) {
                for (Element element : es) {
                    retMap.put(element.getName(), element.getValue());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return retMap;
    }

}
